module dgl.Vector3;

import str = std.string;
import std.math;
import dgl.Vector2;

struct Vector3
{
	private float[3] m_vector;

	public float x()
	{
		return m_vector[0];
	}

	public float y()
	{
		return m_vector[1];
	}

	public float z()
	{
		return m_vector[2];
	}

	public void x( float x )
	{
		m_vector[0] = x;
	}

	public void y( float y )
	{
		m_vector[1] = y;
	}

	public void z( float z )
	{
		m_vector[2] = z;
	}

	public float * ptr()
	{
		return m_vector.ptr;
	}

	public static Vector3 opCall( float x, float y, float z )
	{
		Vector3 ret;
		ret.x = x;
		ret.y = y;
		ret.z = z;
		return ret;
	}

	public static Vector3 opCall( float value )
	{
		Vector3 ret;
		ret.x = value;
		ret.y = value;
		ret.z = value;
		return ret;
	}

	public static Vector3 opCall( Vector2 value, float z )
	{
		Vector3 ret;
		ret.x = value.x;
		ret.y = value.y;
		ret.z = z;
		return ret;
	}

	public static Vector3 zero()
	{
		return Vector3( 0, 0, 0 );
	}
	
	public static Vector3 one()
	{
		return Vector3( 1, 1, 1 );
	}
	
	public static Vector3 unitX()
	{
		return Vector3( 1, 0, 0 );
	}
	
	public static Vector3 unitY()
	{
		return Vector3( 0, 1, 0 );
	}
	
	public static Vector3 unitZ()
	{
		return Vector3( 0, 0, 1 );
	}

	public static Vector3 cross( Vector3 vector1, Vector3 vector2 )
	{
		Vector3 vector;
		vector.x = ( vector1.y * vector2.z ) - ( vector1.z * vector2.y );
		vector.y = ( vector1.z * vector2.x ) - ( vector1.x * vector2.z );
		vector.z = ( vector1.x * vector2.y ) - ( vector1.y * vector2.x );
		return vector;
	}

	public static Vector3 normalize( Vector3 value )
	{
		Vector3 vector;
		float num2 = ( ( value.x * value.x ) + ( value.y * value.y ) ) + ( value.z * value.z );
		float num = 1f / sqrt( num2 );
		vector.x = value.x * num;
		vector.y = value.y * num;
		vector.z = value.z * num;
		return vector;
	}

	public static float dot( Vector3 vector1, Vector3 vector2 )
	{
		return ( ( ( vector1.x * vector2.x ) + ( vector1.y * vector2.y ) ) + ( vector1.z * vector2.z ) );
	}

	public Vector3 opSub( Vector3 value )
	{
		Vector3 vector;
		vector.x = this.x - value.x;
		vector.y = this.y - value.y;
		vector.z = this.z - value.z;
		return vector;
	}
	
	public Vector3 opDiv( float value )
	{
		Vector3 vector;
		vector.x = this.x / value;
		vector.y = this.y / value;
		vector.z = this.z / value;
		return vector;
	}

	public string toString()
	{
		string ret = "";
		ret ~= "{ " ~ str.toString( x );
		ret ~= ", " ~ str.toString( y );
		ret ~= ", " ~ str.toString( z );
		ret ~= " }";
		return ret;
	}
}